package mutsumimod.util;

import basemod.BaseMod;
import basemod.interfaces.PostInitializeSubscriber;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import mutsumimod.cards.BaseCard;
import mutsumimod.util.tags.CustomTags;

import java.util.*;
import java.util.stream.Collectors;

public class CardUtils implements PostInitializeSubscriber {

    public static HashMap<String, BaseCard> modCards = new HashMap<>();
    public static HashMap<String, BaseCard> commonCards = new HashMap<>();
    public static HashMap<String, BaseCard> uncommonCards = new HashMap<>();
    public static HashMap<String, BaseCard> rareCards = new HashMap<>();

    public static void initializeModCards(){
        ArrayList<AbstractCard> cards = BaseMod.getCustomCardsToAdd();
        for (AbstractCard card : cards) {
            if (card instanceof BaseCard ) {
                BaseCard baseCard = (BaseCard) card;
                modCards.put(baseCard.cardID,baseCard);
                switch (baseCard.rarity) {
                    case COMMON:
                        commonCards.put(baseCard.cardID,baseCard);
                        break;
                    case UNCOMMON:
                        uncommonCards.put(baseCard.cardID,baseCard);
                        break;
                    case RARE:
                        rareCards.put(baseCard.cardID,baseCard);
                        break;
                }
            }
        }
    }

    public static ArrayList<AbstractCard> getUnRepeatableRandomCards(int count, AbstractCard.CardRarity rarity, AbstractCard... ignores) {
        ArrayList<AbstractCard> result = new ArrayList<>();
        HashMap<String, BaseCard> targetMap = getTargetMap(rarity);

        if (targetMap == null || targetMap.isEmpty()) return result;

        ArrayList<BaseCard> candidates = new ArrayList<>(targetMap.values());
        Set<String> excludeIds = Arrays.stream(ignores)
                .map(c -> c.cardID)
                .collect(Collectors.toSet());

        Collections.shuffle(candidates, new Random(AbstractDungeon.miscRng.randomLong()));

        for (BaseCard card : candidates) {
            if (result.size() >= count) break;
            if (!excludeIds.contains(card.cardID) && !(card.hasTag(CustomTags.SELF_CARD))) {
                result.add(card);
                excludeIds.add(card.cardID);
            }
        }
        return result;
    }

    public static AbstractCard getRandomCard(AbstractCard.CardRarity rarity){
        return getUnRepeatableRandomCards(1,rarity).get(0);
    }

    public static HashMap<String, BaseCard> getTargetMap(AbstractCard.CardRarity rarity) {
        switch (rarity) {
            case COMMON: return commonCards;
            case UNCOMMON: return uncommonCards;
            case RARE: return rareCards;
            default: return null;
        }
    }

    public static AbstractCard.CardRarity getNextCardRarity(AbstractCard.CardRarity rarity) {
        switch (rarity) {
            case COMMON:
                return AbstractCard.CardRarity.UNCOMMON;
            case UNCOMMON:
            case RARE:
                return AbstractCard.CardRarity.RARE;
        }
        return AbstractCard.CardRarity.RARE;
    }

    @Override
    public void receivePostInitialize() {
        initializeModCards();
    }
}
